﻿#include "deviceinstancemanager.h"
#include <QSet>
#include <QMutex>
#include <QCoreApplication>
#include <QThread>
#include <QAbstractEventDispatcher>

// 初始化静态成员
QSet<QObject *> DeviceInstanceManager::s_managedInstances;
QMutex DeviceInstanceManager::s_mutex;

// 自动清理器，确保程序退出时调用 destroyAllInstances
namespace {
struct InstanceAutoCleaner {
    ~InstanceAutoCleaner()
    {
        DeviceInstanceManager::destroyAllInstances();
    }
};
static InstanceAutoCleaner cleaner;
} // namespace

static inline bool threadHasEventLoop(QThread *th)
{
    return th && th->isRunning() && QAbstractEventDispatcher::instance(th);
}
bool DeviceInstanceManager::destroyInstance(void *instance)
{
    if (!instance)
        return false;

    QObject *qobject_instance = static_cast<QObject *>(instance);
    QMutexLocker locker(&s_mutex);

    if (!s_managedInstances.remove(qobject_instance)) {
        qWarning() << " not tracked, " << qobject_instance;
        return false;
    }
    QThread *target = qobject_instance->thread();
    const bool crossThread = target && (target != QThread::currentThread());

    if (crossThread) {
        if (threadHasEventLoop(target)) {
            // 在目标线程排队删除
            QMetaObject::invokeMethod(qobject_instance, &QObject::deleteLater, Qt::QueuedConnection);
        } else {
            // 目标线程无事件循环/已结束：兜底
            // 注意：若驱动析构严格要求在其原线程执行，这里应改为“在退出前确保线程事件循环仍在，并提前清理实例”。
            qobject_instance->moveToThread(QThread::currentThread());
            delete qobject_instance;
        }
    } else {
        delete qobject_instance;
    }
    return true;
}

void DeviceInstanceManager::destroyAllInstances()
{
    QSet<QObject *> toDelete;
    {
        QMutexLocker locker(&s_mutex);
        if (s_managedInstances.isEmpty())
            return;
        toDelete = s_managedInstances;
        s_managedInstances.clear();
    }

    for (QObject *obj : qAsConst(toDelete)) {
        QThread *target = obj->thread();
        if (target && target != QThread::currentThread()) {
            if (target->isRunning() && QAbstractEventDispatcher::instance(target)) {
                QMetaObject::invokeMethod(obj, &QObject::deleteLater, Qt::QueuedConnection);
            } else {
                obj->moveToThread(QThread::currentThread());
                delete obj;
            }
        } else {
            delete obj;
        }
    }

    // 如果 LibraryFactory 里移除了自动清理器，这里销库，确保顺序：先删对象，再卸库
    LibraryFactory::cleanup();
}
